﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using Intorise.Common;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Web;
using System.Threading;
using System.Net.Sockets;
using System.Drawing;
using System.IO;

namespace Model
{
    public class GmBotEngine : BotEngine
    {
        string LOGIN_DATA = "uname={0}&password={1}&forward=%252Fplay_games%252Fplay%252Fserver%252Fmu%252Fid%252F{2}&remember=checked&ckcode={3}";
        string getCodeUrl = "http://www.gm99.com/verify_image?rnd=0.9111005463337411";
        string checkCodeUrl = "http://www.gm99.com/ajax/check_code?ckcode={0}";
        string loginUrl = "http://www.gm99.com/login/login2/";
        string enterGameUrl = "http://www.gm99.com/play_games/play/server/mu/id/";
        string registerUrl = "http://apidts.gm99.com/client/?user_name={0}&server_id=S{1}&is_adult=-1&time={2}&sign=dc4af81336e641eb9de7183d89588271&client=1";
        string registerServerUrl = null;

        public GmBotEngine(Player player) : base(player) { }

        public override bool RemoteLogin()
        {
            CookieContainer cookies = new CookieContainer();
            ConsoleBLL.WriteLine(player + " 开始登录...");
            var request = net.SendRequest("http://www.gm99.com/mu/", "GET", cookies);
            var response = (HttpWebResponse)request.GetResponse();
            var html = net.GetResponseHtml(response);
            JObject result = null;
            var code = "";

            while (true)
            {
                code = GetLocalCode(cookies);
                ConsoleBLL.WriteLine("计算验证码：" + code);
                request = net.SendRequest(string.Format(checkCodeUrl, code), "GET", cookies);
                html = net.GetResponseHtml(request);
                result = (JObject)JsonConvert.DeserializeObject(html);
                ConsoleBLL.WriteLine(result["msg"].ToString());
                if (result["result"].ToString() == "1")
                {
                    break;
                }
                Thread.Sleep(100);
            }

            request = net.SendRequest(loginUrl, "POST", cookies);
            net.PostData(string.Format(LOGIN_DATA, player.AccountName, player.PlayerAccount.Password, player.ServerID, code), request);

            response = (HttpWebResponse)request.GetResponse();
            html = net.GetResponseHtml(response);

            html = html.Replace("staticLogin_JSONPMethod(", "").Replace(")", "");
            result = (JObject)JsonConvert.DeserializeObject(html);
            if (infoLog)
            {
                ConsoleBLL.WriteLineInfo(player + " login result:" + result);
            }
            var flag = result["result"].ToString();
            switch (flag)
            {
                case "1":
                    ConsoleBLL.WriteLineError(player + " 用户名密码正确，登录成功，进入游戏...");
                    break;
                default:
                    ConsoleBLL.WriteLineError(player + " 登录失败，账户密码错误");
                    ConsoleBLL.WriteLine(html.ToString());
                    this.player.Status = PlayerStatusEnum.账户密码错误;
                    return false;
            }

            request = net.SendRequest(enterGameUrl + player.ServerID, "GET", cookies);
            html = net.GetResponseHtml(request);

            //获取登录游戏服务器的地址


            var url = Tools.SubString(html, "<iframe src=\"", "\" name=\"playFrame\"", true);
            if (url == "/index/busy/?on=play_default")
            {
                ConsoleBLL.WriteLineWaring("游戏正在维护"); player.Status = PlayerStatusEnum.停止; return false;
            }
            request = net.SendRequest(url, "GET", cookies);
            html = net.GetResponseHtmlGzip(request);

            if (infoLog)
            {
                ConsoleBLL.WriteLineInfo(player + " login enterGameUrl:" + request.RequestUri);
            }

            port = GameHelper.GetPort(html);
            if (port == 0)
            {
                ConsoleBLL.WriteLineError(player + " 无法获取服务器端口，html:");
                ConsoleBLL.WriteLine(html);
                return false;
            }
            head = new byte[] { 0x00, 0x0A, 0xAF, 0x30 };

            //http://apidts.gm99.com/client/?user_name=qq314297760&server_id=S30057&is_adult=-1&time=1462722318&sign=8df51d5cb1ca7d194d18a2b54d903343&client=1
            serverNo = Tools.GetAscII(Tools.SubString(url.ToLower(), "server_id=s", "&", true));
            accountData = Tools.GetAscII(Tools.SubString(url, "user_name=", "&", true));
            time = Tools.GetAscII(GameHelper.GetTime(html));
            singn = Tools.GetAscII(GameHelper.GetSign(html));
            ip = GameHelper.GetIP(html);

            return true;
        }

        public override bool EnterGameServer()
        {
            DateTime startTime = DateTime.Now;
            Client = new TcpClient(ip, 843);
            var data = Tools.GetAscII("<policy-file-request/>\0");
            net.SendData(Client, data);
            Client.Close();

            Client = new TcpClient(ip, port);
            Begin();

            data = Tools.Contact(head, DataPackager.GetNetworkData((short)serverNo.Length), serverNo, net.GetNetworkBytes((short)accountData.Length), accountData, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A }
                , time, new byte[] { 0x00, 0x01, 0x31, 0x00, 0x20 }, singn
                , new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x75, 0x6E, 0x64, 0x65, 0x66, 0x69, 0x6E, 0x65, 0x64, 0x00, 0x00,0x00,0x02,0x2D,0x31 });
            data = Tools.Contact(net.GetNetworkBytes(data.Length), data);
            net.SendData(Client, data, data.Length);

            while (!player.Entered)
            {
                Thread.Sleep(300);
                if (player.Config.TimeoutLogin < (DateTime.Now - startTime).TotalSeconds) { break; }
            }

            if (!player.Entered)
            {
                ConsoleBLL.WriteLineWaring(player + " 进入游戏超时！");
                Stop();
            }
            return player.Entered;
        }

        private string GetLocalCode(CookieContainer cookies)
        {
            //http://gameapp.37.com/controller/code.php
            var request = net.SendRequest(getCodeUrl, "GET", cookies);
            var data = net.GetResponseData((HttpWebResponse)request.GetResponse(), false);
            using (MemoryStream stream = new MemoryStream(data))
            {
                Image image = Image.FromStream(stream);
                var form = new CodeForm();
                form.Show(image);
                return form.Code;
                return GameHelper.GetCode(image);
            }
        }
    }
}
